package com.insight.repository;

import com.insight.entity.MetadataTable;
import com.insight.entity.TableRelationship;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

/**
 * T111: TableRelationship Repository接口
 * 表关系数据访问层,支持图遍历查询
 *
 * @author Insight Team
 */
@Repository
public interface TableRelationshipRepository extends JpaRepository<TableRelationship, Long> {

    /**
     * 查询源表的所有关系(子表查找其外键指向的父表)
     * 用于查询某个表作为子表时的所有外键关系
     *
     * @param sourceTable 源表(子表)
     * @return 关系列表
     */
    List<TableRelationship> findBySourceTable(MetadataTable sourceTable);

    /**
     * 查询目标表的所有关系(父表查找引用它的子表)
     * 用于查询某个表作为父表时被哪些子表引用
     *
     * @param targetTable 目标表(父表)
     * @return 关系列表
     */
    List<TableRelationship> findByTargetTable(MetadataTable targetTable);

    /**
     * 根据源表和约束名称查询关系
     * 约束名在同一源表内唯一
     *
     * @param sourceTable    源表
     * @param constraintName 约束名称
     * @return 关系Optional
     */
    Optional<TableRelationship> findBySourceTableAndConstraintName(
            MetadataTable sourceTable, String constraintName);

    /**
     * 查询源表ID的所有关系
     *
     * @param sourceTableId 源表ID
     * @return 关系列表
     */
    @Query("SELECT tr FROM TableRelationship tr WHERE tr.sourceTable.id = :sourceTableId")
    List<TableRelationship> findBySourceTableId(@Param("sourceTableId") Long sourceTableId);

    /**
     * 查询目标表ID的所有关系
     *
     * @param targetTableId 目标表ID
     * @return 关系列表
     */
    @Query("SELECT tr FROM TableRelationship tr WHERE tr.targetTable.id = :targetTableId")
    List<TableRelationship> findByTargetTableId(@Param("targetTableId") Long targetTableId);

    /**
     * 查询表的所有关系(作为源表或目标表)
     * 用于图遍历,获取表的完整关系视图
     *
     * @param tableId 表ID
     * @return 关系列表
     */
    @Query("SELECT tr FROM TableRelationship tr " +
            "WHERE tr.sourceTable.id = :tableId OR tr.targetTable.id = :tableId")
    List<TableRelationship> findAllRelationshipsByTableId(@Param("tableId") Long tableId);

    /**
     * 查询数据源下的所有关系
     * 通过源表的数据源ID查询
     *
     * @param dataSourceId 数据源ID
     * @return 关系列表
     */
    @Query("SELECT tr FROM TableRelationship tr " +
            "WHERE tr.sourceTable.dataSource.id = :dataSourceId")
    List<TableRelationship> findByDataSourceId(@Param("dataSourceId") Long dataSourceId);

    /**
     * 根据关系类型查询
     *
     * @param relationType 关系类型(FOREIGN_KEY, UNIQUE, etc.)
     * @return 关系列表
     */
    List<TableRelationship> findByRelationType(String relationType);

    /**
     * 根据约束名称模糊查询
     *
     * @param constraintName 约束名称关键词
     * @return 关系列表
     */
    @Query("SELECT tr FROM TableRelationship tr " +
            "WHERE tr.constraintName LIKE CONCAT('%', :constraintName, '%')")
    List<TableRelationship> searchByConstraintName(@Param("constraintName") String constraintName);

    /**
     * 统计源表的关系数量
     *
     * @param sourceTable 源表
     * @return 关系数量
     */
    long countBySourceTable(MetadataTable sourceTable);

    /**
     * 统计目标表的关系数量
     *
     * @param targetTable 目标表
     * @return 关系数量
     */
    long countByTargetTable(MetadataTable targetTable);

    /**
     * 检查两个表之间是否存在直接关系
     *
     * @param sourceTable 源表
     * @param targetTable 目标表
     * @return 是否存在关系
     */
    boolean existsBySourceTableAndTargetTable(MetadataTable sourceTable, MetadataTable targetTable);

    /**
     * 删除源表的所有关系
     *
     * @param sourceTable 源表
     */
    void deleteBySourceTable(MetadataTable sourceTable);

    /**
     * 删除目标表的所有关系
     *
     * @param targetTable 目标表
     */
    void deleteByTargetTable(MetadataTable targetTable);
}
